package com.gdufe.studytogether.service.group.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gdufe.studytogether.domain.R;
import com.gdufe.studytogether.domain.pojo.*;
import com.gdufe.studytogether.domain.vo.GroupDetail;
import com.gdufe.studytogether.mapper.GroupMapper;
import com.gdufe.studytogether.mapper.UserGroupMapper;
import com.gdufe.studytogether.service.application.ApplicationService;
import com.gdufe.studytogether.service.competition.CompetitionService;
import com.gdufe.studytogether.service.group.GroupService;
import com.gdufe.studytogether.service.user.UserService;
import com.gdufe.studytogether.service.usergroup.UserGroupService;
import com.gdufe.studytogether.utils.UserThreadLocal;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

@Service
public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements GroupService {

    @Autowired
    GroupMapper groupMapper;
    @Autowired
    UserService userService;
    @Autowired
    ApplicationService applicationService;
    @Autowired
    UserGroupMapper userGroupMapper;
    @Autowired
    CompetitionService competitionService;
    @Autowired
    UserGroupService userGroupService;
    @Override
    public R listGroup(Long pageSize,Long pageCurrent,Integer id,String groupName,Integer competitionId) throws Exception {

        Page<Group> page=new Page<>();
        if (pageSize==null){
            pageSize=20L;
        }
        if (pageCurrent==null){
            pageCurrent=1L;
        }
        page.setSize(pageSize);
        page.setCurrent(pageCurrent);
        QueryWrapper<Group> qw=new QueryWrapper<>();
        if(id!=null&&id>0){
            qw.eq("id",id);
        }
        if(groupName!=null&&!groupName.equals("")){
            qw.like("groupName",groupName);
        }
        if(competitionId!=null&&competitionId!=-1){
            qw.like("cid",competitionId);
        }
        qw.orderByDesc("createTime");
        qw.eq("status","0");
        Page<Group> result = this.page(page,qw);
        List<Group> records = result.getRecords();
        for (Group group : records) {
            Integer cid = group.getCid();
            Competition competition = competitionService.getById(cid);
            group.setCname(competition.getName());
            Integer leaderid = group.getLeaderid();
            User user = userService.getById(leaderid);
            group.setLeaderName(user.getUsername());
            group.setLeaderImg(user.getImg());
        }
        return R.ok(result);
    }

    @Override
    public R getGroupDetail(Long pageSize,Long pageCurrent,Integer id,String groupName,Integer competitionId) throws Exception {

        Page<Group> page=new Page<>();
        if (pageSize==null){
            pageSize=1000L;
        }
        if (pageCurrent==null){
            pageCurrent=1L;
        }
        page.setSize(pageSize);
        page.setCurrent(pageCurrent);
        QueryWrapper<Group> groupQueryWrapper = new QueryWrapper<>();
        Integer myUserid = UserThreadLocal.get();


        if(id!=null&&id>0){
            groupQueryWrapper.eq("id",id);
        }
        if(groupName!=null&&!groupName.isEmpty()){
            groupQueryWrapper.like("groupName",groupName);
        }
        if(competitionId!=null&&competitionId>0){
            groupQueryWrapper.eq("cid",competitionId);
        }
        groupQueryWrapper.eq("status","0");


        QueryWrapper<UserGroup> uGQueryWrapper = new QueryWrapper<>();
        uGQueryWrapper.select("gid").eq("uid",myUserid);
        List<UserGroup> userGroups1 = userGroupMapper.selectList(uGQueryWrapper);
        List<Integer> gidList = userGroups1.stream().map(UserGroup::getGid).collect(Collectors.toList());
        if (gidList.size()>0){
            groupQueryWrapper.and(wrapper->wrapper.eq("leaderid",myUserid).or().in("id",gidList));
        }else{
            groupQueryWrapper.eq("leaderid",myUserid);
        }
        Page<Group> page1 = groupMapper.selectPage(page, groupQueryWrapper);
        List<Group> groups = page1.getRecords();
        for (Group record : groups) {
            Integer groupId = record.getId();
            Integer leaderid = record.getLeaderid();

            //记录队长信息
            User leader = userService.getById(leaderid);
            record.setLeaderName(leader.getUsername());
            record.setLeaderImg(leader.getImg());
            //记录比赛名称
            Integer cid = record.getCid();
            Competition competition = competitionService.getById(cid);
            record.setCname(competition.getName());
            //收集成员信息
            QueryWrapper<UserGroup> userGroupQueryWrapper = new QueryWrapper<>();
            userGroupQueryWrapper.eq("gid",groupId);
            List<UserGroup> userGroups = userGroupMapper.selectList(userGroupQueryWrapper);
            List<User> members=new ArrayList<>();
            for (UserGroup userG : userGroups) {
                Integer uid = userG.getUid();
                User user = userService.getById(uid);
                members.add(user);
            }
            record.setMembers(members);

            /*if(leaderid==myUserid){
                //我是队长
                //记录队长信息
                User leader = userService.getById(leaderid);
                record.setLeaderName(leader.getUsername());
                record.setLeaderImg(leader.getImg());
                //记录比赛名称
                Integer cid = record.getCid();
                Competition competition = competitionService.getById(cid);
                record.setCname(competition.getName());
                //收集成员信息
                QueryWrapper<UserGroup> userGroupQueryWrapper = new QueryWrapper<>();
                userGroupQueryWrapper.eq("gid",groupId);
                List<UserGroup> userGroups = userGroupMapper.selectList(userGroupQueryWrapper);
                List<User> members=new ArrayList<>();
                for (UserGroup userG : userGroups) {
                    Integer uid = userG.getUid();
                    User user = userService.getById(uid);
                    members.add(user);
                }
                record.setMembers(members);
            }else{
                //我是队员
                QueryWrapper<UserGroup> qw=new QueryWrapper<>();
                qw.eq("gid",groupId);
                qw.eq("uid",myUserid);
                UserGroup userGroup = userGroupMapper.selectOne(qw);
                if(userGroup!=null){
                    //记录比赛名称
                    Integer cid = record.getCid();
                    Competition competition = competitionService.getById(cid);
                    record.setCname(competition.getName());
                    //记录队长信息
                    User leader = userService.getById(leaderid);
                    record.setLeaderName(leader.getUsername());
                    record.setLeaderImg(leader.getImg());
                    //收集成员信息
                    QueryWrapper<UserGroup> userGroupQueryWrapper = new QueryWrapper<>();
                    userGroupQueryWrapper.eq("gid",groupId);
                    List<UserGroup> userGroups = userGroupMapper.selectList(userGroupQueryWrapper);
                    List<User> members=new ArrayList<>();
                    for (UserGroup userG : userGroups) {
                        Integer uid = userG.getUid();
                        User user = userService.getById(uid);
                        members.add(user);
                    }
                    record.setMembers(members);
                }
            }*/
        }

        return R.ok(page1);
    }

    @Override
    @Transactional
    public R addGroup(Group group) throws Exception {
        Integer uid = UserThreadLocal.get();

        Integer cid = group.getCid();
        Competition competition = competitionService.getById(cid);
        if (competition==null){
            return R.error("比赛未找到");
        }
        if(!"0".equals(competition.getStatus())){
            return R.error("比赛不存在");
        }
        LocalDate now = LocalDate.now();
        LocalDate endTime = competition.getEndTime();
        if (now.isAfter(endTime)){
            return R.error("比赛已结束");
        }
        QueryWrapper<Group> groupQueryWrapper = new QueryWrapper<>();
        groupQueryWrapper.eq("groupName",group.getGroupName());
        groupQueryWrapper.eq("status","0");
        List<Group> groups = groupMapper.selectList(groupQueryWrapper);
        if (groups!=null&&groups.size()>0){
            return R.error("队伍名称已被使用，请更改");
        }
        //查看在该比赛是否已经加入了队伍
        List<Integer> groupIdByUId = groupMapper.getGroupIdByUIdAndCid(uid,cid);
        if (groupIdByUId.size()>0){
            for(Integer gid:groupIdByUId){
                QueryWrapper<Group> qw = new QueryWrapper<>();
                qw.eq("status", "0");
                qw.eq("id",gid);
                List<Group> list = list(qw);
                if(list.size()>0){
                    return R.error("您已加入其他队伍，无法创建新队伍");
                }
            }
        }
        //查看是否已创建了队伍
        QueryWrapper<Group> qw=new QueryWrapper<>();
        qw.eq("cid",cid);
        qw.eq("leaderid",uid);
        qw.eq("status","0");
        List<Group> groups1 = groupMapper.selectList(qw);
        if (groups1.size()>0){
            return R.error("您已加入其他队伍，无法创建新队伍");
        }

        String groupName = group.getGroupName();
        Integer memberSize = group.getMemberSize();
        if (groupName==null|| groupName.equals("")){
            return R.error("请输入正确的队伍名");
        }
        if (memberSize==null||memberSize<=0){
            return R.error("请输入正确的成员数量");
        }

        if (group.getMotto()==null){
            return R.error("请输入队伍简介");
        }

        if(group.getMemberRequire()==null){
            return R.error("请输入成员要求");
        }

        if (group.getQqNumber()==null&&group.getWxNumber()==null&&group.getPhone()==null){
            return R.error("请至少提供一种联系方式");
        }

        group.setLeaderid(uid);
        group.setCurrentSize(1);
        group.setCreateTime(LocalDate.now());
        int i = groupMapper.insert(group);
        if (i<=0){
            throw new Exception("创建队伍失败");
        }


        return R.ok();

    }

    @Override
    @Transactional
    public R deleteGroup(Integer id) throws Exception {
        Group group = groupMapper.selectById(id);
        Integer leaderid = group.getLeaderid();
        Integer uid = UserThreadLocal.get();
        if (leaderid!=uid){
            return R.error("解散队伍失败，只有队长才能解散队伍");
        }
        UpdateWrapper<Group> groupUpdateWrapper = new UpdateWrapper<>();
        groupUpdateWrapper.eq("id",id);
        groupUpdateWrapper.set("status","1");

        groupMapper.update(null,groupUpdateWrapper);
        applicationService.deleteApplicationByGid(id);

        return R.ok();
    }

    @Override
    public R joinGroup(Application application) throws Exception {
        Group group = groupMapper.selectById(application.getGid());
        if (group!=null&&"0".equals(group.getStatus())){
            Integer currentSize = group.getCurrentSize();
            Integer memberSize = group.getMemberSize();
            if (currentSize>=memberSize){
                throw new Exception("已满员");//已满员
            }
            group.setCurrentSize(currentSize+1);
            int i = groupMapper.updateById(group);
            if(i<=0){
                throw new Exception("修改队伍人数失败");
            }
            UserGroup userGroup = new UserGroup();
            userGroup.setUid(application.getUid());
            userGroup.setGid(application.getGid());
            userGroup.setCid(group.getCid());
            boolean save = userGroupService.save(userGroup);
            if (!save){
                throw new Exception("添加用户——队伍信息失败");
            }
            return R.ok();
        }else{
            throw new Exception("队伍不存在");
        }
    }


    @Override
    @Transactional
    public R exitGroup(Integer gid) throws Exception {
        Group group = groupMapper.selectById(gid);
        if (group==null||!"0".equals(group.getStatus())){
            throw new Exception("队伍不存在");
        }
        Integer uid = UserThreadLocal.get();
        if (group.getLeaderid().equals(uid)){
            return R.error("队长无法退出队伍");
        }
        Integer i1 = groupMapper.countdownGroupSize(gid);
        Integer i = groupMapper.deleteUserGroupByGidAndUid(gid, uid);
        Application application = new Application();
        application.setType("3");
        application.setUid(uid);
        application.setGid(gid);
        application.setTargetId(group.getLeaderid());
        applicationService.save(application);

        return R.ok();
    }

    @Override
    public R removeMember(Integer gid, Integer uid) throws Exception {
        Integer currentuid = UserThreadLocal.get();
        Group group = groupMapper.selectById(gid);
        if (group==null||!"0".equals(group.getStatus())){
            return R.error("队伍不存在");
        }
        if (group.getLeaderid()!=currentuid){
            return R.error("只有队长才可修改");
        }
        QueryWrapper<UserGroup> qw = new QueryWrapper<>();
        qw.eq("gid",gid);
        qw.eq("uid",uid);
         userGroupService.remove(qw);

            group.setCurrentSize(group.getCurrentSize()-1);
            groupMapper.updateById(group);
            Application application = new Application();
            application.setUid(uid);
            application.setGid(gid);
            application.setTargetId(uid);
            application.setType("4");
            applicationService.save(application);
            return R.ok();

    }

    @Override
    @Transactional
    public R updateGroup(Group group) throws Exception {
        Integer id = group.getId();
        group.setCurrentSize(null);
        Group group1 = groupMapper.selectById(id);
        if (group1==null||!"0".equals(group.getStatus())){
            return R.error("队伍不存在");
        }
        Integer uid = UserThreadLocal.get();
        if (group1.getLeaderid()!=uid){
            return R.error("只有队长才能编辑队伍信息");
        }

        Integer cid = group.getCid();
        Competition competition = competitionService.getById(cid);
        if (competition==null||!"0".equals(competition.getStatus())){
            return R.error("比赛未找到");
        }
        LocalDate now = LocalDate.now();
        LocalDate endTime = competition.getEndTime();
        if (now.isAfter(endTime)){
            return R.error("比赛已结束");
        }
        QueryWrapper<Group> groupQueryWrapper = new QueryWrapper<>();
        groupQueryWrapper.eq("groupName",group.getGroupName());
        groupQueryWrapper.ne("id",id);
        groupQueryWrapper.eq("status","0");
        List<Group> groups = groupMapper.selectList(groupQueryWrapper);
        if (groups!=null&&groups.size()>0){
            return R.error("队伍名称已被使用，请更改");
        }
        //查看在该比赛是否已经加入了队伍
        List<Integer> groupIdByUId = groupMapper.getGroupIdByUIdAndCid(uid,cid);
        if (groupIdByUId.size()>0){
            for (Integer gid : groupIdByUId) {
                QueryWrapper<Group> qw = new QueryWrapper<>();
                qw.eq("id",gid);
                qw.eq("status","0");
                List<Group> groups1 = groupMapper.selectList(qw);
                if(groups1.size()>0){
                    return R.error("您已加入其他队伍，无法创建新队伍");
                }
            }

        }
        //查看是否已创建了队伍
        QueryWrapper<Group> qw=new QueryWrapper<>();
        qw.eq("cid",cid);
        qw.eq("leaderid",uid);
        qw.ne("id",id);
        qw.eq("status","0");
        List<Group> groups1 = groupMapper.selectList(qw);
        if (groups1.size()>0){
            return R.error("您已加入其他队伍，无法创建新队伍");
        }

        String groupName = group.getGroupName();
        Integer memberSize = group.getMemberSize();
        if (groupName==null|| groupName.equals("")){
            return R.error("请输入正确的队伍名");
        }
        if (memberSize==null||memberSize<=0){
            return R.error("请输入正确的成员数量");
        }

        if (memberSize<group1.getCurrentSize()){
            return R.error("成员数量上限小于当前成员数量");
        }

        if (group.getMotto()==null){
            return R.error("请输入队伍简介");
        }

        if(group.getMemberRequire()==null){
            return R.error("请输入成员要求");
        }

        if (group.getQqNumber()==null&&group.getWxNumber()==null&&group.getPhone()==null){
            return R.error("请至少提供一种联系方式");
        }

        group.setCreateTime(null);
        groupMapper.updateById(group);

        QueryWrapper<UserGroup> userGroupQueryWrapper = new QueryWrapper<>();
        userGroupQueryWrapper.eq("gid",id);
        UserGroup userGroup = new UserGroup();
        userGroup.setCid(cid);
        userGroupService.update(userGroup,userGroupQueryWrapper);
        return R.ok();
    }


}
